package com.ruoyi.common.utils.ftp;


import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;


/**
 * @ClassName FtpUtil
 * @Description TODO
 * @Author luguanqing
 * @Date 2021/6/21 11:04
 * @Version 1.0
 */
public class FtpUtil {

    private final static Log logger = LogFactory.getLog(FtpUtil.class);

    /**
     * 本地字符编码
     */
    private static String LOCAL_CHARSET = "GBK";

    //Ftp协议文件名编码iso-8859-1
    private static String SERVER_CHARSET = "ISO-8859-1";

    /**
     * 获取ftpclient对象
     */
    public static FTPClient getFTPClient(String ftphost, int ftpPort, String ftpUserName, String ftpPassword){
        FTPClient ftpClient = null;
        try{
            ftpClient = new FTPClient();
            //连接ftp服务器
            ftpClient.connect(ftphost, ftpPort);
            //登录ftp服务器
            ftpClient.login(ftpUserName, ftpPassword);
            if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())){
                logger.info("未连接到ftp，用户名或密码错误");
                ftpClient.disconnect();
            }else{
                logger.info("ftp连接成功。");
            }
        }  catch (SocketException e){
            e.printStackTrace();
            logger.info("ftp的ip地址有误，请正确配置。");
        }   catch (IOException e){
            e.printStackTrace();
            logger.info("ftp的端口错误，请正确配置");
        }
        return ftpClient;
    }

    /**
     * 从ftp下载文件
     */
    public static void downloadFtpFile(String ftpHost, String ftpUsername, String ftpPassword, int ftpPort, String ftpPath, String localPath, String fileName){
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient(ftpHost, ftpPort, fileName, ftpPassword);
            //设置上传文件类型为二进制
            if(FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))){
                LOCAL_CHARSET = "UTF-8";
            }
            ftpClient.setControlEncoding(LOCAL_CHARSET);
            //设置被动模式
            ftpClient.enterLocalPassiveMode();
            //设置传输模式
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            //上传文件
            //转码中文文件
            String fileNameTemp = new String(fileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
            ftpClient.changeWorkingDirectory(ftpPath);
            InputStream retrieveFileStream = ftpClient.retrieveFileStream(fileNameTemp);
            //文件下载流
            byte[] input2byte = input2byte(retrieveFileStream);
            byte2File(input2byte, localPath, fileName);
            if(null != retrieveFileStream){
                retrieveFileStream.close();
            }
        }catch (FileNotFoundException e){
         logger.error("未找到" + ftpPath + "文件");
         e.printStackTrace();
        }catch (SocketException e){
            logger.error("连接ftp失败");
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
            logger.error("文件读取错误");
            e.printStackTrace();
        }finally {
            if(ftpClient.isConnected()){
                try{
                    //退出登录
                    ftpClient.logout();
                    //关闭连接
                    ftpClient.disconnect();
                }catch (IOException e){

                }
            }
        }
    }

    //字节数组转为输入流
    public static final InputStream byte2Input(byte[] buf){
        return new ByteArrayInputStream(buf);
    }

    //将输入流转为byte[]
    public static final byte[] input2byte(InputStream inStream) throws IOException{
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[100];
        int rc = 0;
        while((rc = inStream.read(buff, 0 , 100)) > 0){
            swapStream.write(buff, 0, rc);
        }
        byte[] in2b = swapStream.toByteArray();
        return in2b;
    }

    //将byte[]转为文件
    public static void byte2File(byte[] buf, String filePath, String fileName){
        BufferedOutputStream bos = null;
        FileOutputStream fos = null;
        File file = null;
        try{
            File dir = new File(filePath);
            if(!dir.exists() && dir.isDirectory()){
                dir.mkdirs();
            }
            file = new File(filePath + File.separator + fileName);
            fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            bos.write(buf);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(bos != null){
                try{
                    bos.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
            if(fos != null){
                try{
                    fos.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 向ftp服务器上传文件
     */
    public static boolean uploadFile(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String basePath, String filePath, String fileName, InputStream input){
        boolean result = false;
        FTPClient ftpClient = null;
        try{
            int reply;
            ftpClient = getFTPClient(ftpHost, ftpPort, ftpUserName, ftpPassword);
            reply = ftpClient.getReplyCode();
            if(!FTPReply.isPositiveCompletion(reply)){
                ftpClient.disconnect();
                return result;
            }
            //切换上传目录
            if(!ftpClient.changeWorkingDirectory(basePath + filePath)){
                //不存在创建目录
                String[] dirs = filePath.split("/");
                String tempPath = basePath;
                for(String dir : dirs){
                    if(null == dir || "".equals(dir)){
                        continue;
                    }
                    tempPath += "/" + dir;
                    if(!ftpClient.changeWorkingDirectory(tempPath)){
                        if(!ftpClient.makeDirectory(tempPath)){
                            return result;
                        }else {
                            ftpClient.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            //设置上传文件的类型为二进制类型
            if(FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))){
                LOCAL_CHARSET = "UTF-8";
            }
            ftpClient.setControlEncoding(LOCAL_CHARSET);
            //设置被动模式
            ftpClient.enterLocalPassiveMode();
            //设置传输模式
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            //上传文件
            fileName = new String(fileName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
            if(!ftpClient.storeFile(fileName, input)){
                return result;
            }
            if(null != input){
                input.close();
            }
            result = true;
        }catch (IOException e){
            e.printStackTrace();
        } finally {
            if(ftpClient.isConnected()){
                try {
                    //退出登录
                    ftpClient.logout();
                    //关闭连接
                    ftpClient.disconnect();
                }catch (IOException e){}
            }
        }
        return result;
    }

    /**
     * 删除文件
     */
    public static  boolean deleteFile(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword, String pathname, String filename){
        boolean flag = false;
        FTPClient ftpClient = new FTPClient();
        try{
            ftpClient = getFTPClient(ftpHost, ftpPort, ftpUserName, ftpPassword);
            //验证是否登录成功
            int replyCode = ftpClient.getReplyCode();
            if(!FTPReply.isPositiveCompletion(replyCode)){
                return flag;
            }
            //切换ftp目录
            ftpClient.changeWorkingDirectory(pathname);
            //设置上传文件的类型为二进制
            if(FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))){
                LOCAL_CHARSET = "UTF-8";
            }
            ftpClient.setControlEncoding(LOCAL_CHARSET);
            //设置被动模式
            ftpClient.enterLocalPassiveMode();
            //设置传输的模式
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            //中文名称转码
            filename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
            ftpClient.dele(filename);
            flag = true;
        }  catch (Exception e){
            e.printStackTrace();
        }  finally {
            if(ftpClient.isConnected()){
                try{
                    //退出登录
                    ftpClient.logout();
                    //关闭连接
                    ftpClient.disconnect();
                }catch (IOException e){}
            }
        }
        return flag;
    }
}
